
cfile_path = 'D:\\SVN\\MCU\\M0\\HK32ATCH_523\\04_例程\\02_ExampleCode\\Example\\COMP\\COMP_EXTI\\src\\main.c'
# cfile_path = 'test.c'
import chardet

# from pycparser import parse_file
# # 指定要解折的C文件路经
# #解桥工件
# ast = parse_file(cfile_path)
# print(f'ast--{ast}')


# from pycparser import c_parser, c_ast
# # 定义访问者类
# class FuncVisitor(c_ast.NodeVisitor):
#     def visit_FuncDef(self, node):
#         # 打印函数名
#         print("函数名:", node.decl.name)
#         # 打印函数返回类型
#         print("返回类型:", node.decl.type.type.names[0])
#         # 打印函数参数
#         print("参数:")
#         for param in node.decl.type.args.params:
#             print(param.type.type.names[0], param.name)
#         print()
# # 读取 C 文件内容
# with open(cfile_path, 'r') as file:
#     content = file.read()
# # 创建 C 语法分析器
# parser = c_parser.CParser()
# # 解析 C 文件
# ast = parser.parse(content)
# # 创建访问者对象
# visitor = FuncVisitor()
# # 遍历 AST（抽象语法树）
# visitor.visit(ast)

# import clang.cindex
# # 加载 C 文件
# index = clang.cindex.Index.create()
# translation_unit = index.parse(cfile_path)
# # 遍历 AST (抽象语法树)
# for node in translation_unit.cursor.walk_preorder():
#     # 提取函数信息
#     if node.kind == clang.cindex.CursorKind.FUNCTION_DECL:
#         function_name = node.spelling
#         function_type = node.type.spelling
#         print("函数名:", function_name)
#         print("函数类型:", function_type)
#         print("参数列表:")
#         for arg in node.get_arguments():
#             arg_name = arg.spelling
#             arg_type = arg.type.spelling
#             print("\t参数名:", arg_name)
#             print("\t参数类型:", arg_type)


# # parser_file 用于处理c语言文件
# from pycparser import parse_file
# # c语言有错误时，会引出此错误
# from pycparser.plyparser import ParseError
# # c_ast.py 文件下包含了抽象语法树的节点类
# from pycparser.c_ast import *

# filename = 'test.c'
# # fake_libc_include文件夹放在处理的c语言目录下
# ast = parse_file(filename, use_cpp = True, cpp_path=r'C:\MinGW\bin\mingw-get.exe', cpp_args=['-E', r'-Iutils/fake_libc_include'])
# # 展示ast结构（官方的方法）
# ast.show()
# # 打印ast节点及其属性
# print(ast)

# from pycparser import c_parser, c_ast
# # 指定要解析的 .c 文件路径
# c_file_path = 'main.c'
# # 读取 .c 文件内容
# with open(c_file_path, 'r') as file:
#     c_code = file.read()
# # 创建 C 语言解析器
# parser = c_parser.CParser()
# # 解析 .c 文件内容
# ast = parser.parse(c_code, filename=c_file_path)
# # 印 AST
# ast.show()


# import clang.cindex
# # 指定要解析的 .c 文件路径
# c_file_path = 'main.c'
# # c_file_path = cfile_path
# # 创建 Clang 解析器
# index = clang.cindex.Index.create()
# # 解析 .c 文件
# translation_unit = index.parse(c_file_path)
# # # 遍历 AST
# # for node in translation_unit.cursor.walk_preorder():
# #     # print(node)
# #     function_name = node.spelling
# #     function_type = node.type.spelling
# #     print("函数名:", function_name)
# #     print("函数类型:", function_type)
# #     # print("参数列表:")
# #     for arg in node.get_arguments():
# #         arg_name = arg.spelling
# #         arg_type = arg.type.spelling
# #         print("\t参数名:", arg_name)
# #         print("\t参数类型:", arg_type)
# # 获取顶层游标
# top_level_cursor = translation_unit.cursor
# # 定义一个递归函数来遍历游标树
# def traverse_cursor(cursor):
#     # 如果游标是宏定义
#     if cursor.kind == clang.cindex.CursorKind.MACRO_DEFINITION:
#         print(f"Macro: {cursor.spelling}")
#     # 如果游标是函数
#     elif cursor.kind == clang.cindex.CursorKind.FUNCTION_DECL:
#         print(f"Function: {cursor.spelling}")

#     # 遍历子游标
#     for child_cursor in cursor.get_children():
#         traverse_cursor(child_cursor)

# # 调用递归函数来遍历顶层游标
# traverse_cursor(top_level_cursor)


# from pygments.lexers import CLexer
# from antlr4 import *
# from CLexer import CLexer
# from CParser import CParser
# # 读取 C 文件内容
# with open('main.c', 'r') as file:
#     c_code = file.read()
# # 创建词法分析器
# lexer = CLexer(InputStream(c_code))
# # 创建词法记号流
# token_stream = CommonTokenStream(lexer)
# # 创建语法分析器
# parser = CParser(token_stream)
# # 解析 C 文件
# parse_tree = parser.compilationUnit()
# # 打印解析树
# # print(tree.toStringTree(recog=parser))

from antlr4 import *
from CParser import CParser
from CLexer import CLexer
from CListener import CListener

class MyCListener(CListener):
    def __init__(self):
        self.functions = []
        self.comments = []
        self.macros = []
        self.parameters = dict()
        

    # def enterPrimaryExpression(self, ctx):
    #     """
    #     解析函数中的语句
    #     Args:
    #         ctx (_type_): _description_
    #     """
    #     macro_name = ctx.getText()
    #     self.macros.append(macro_name)

    # def enterLabeledStatement(self, ctx):
    #     macro_name = ctx.getText()
    #     self.macros.append(macro_name)

    def enterFunctionDefinition(self, ctx):
        function_struct = ctx.getText() # 整个函数
        function_name = ctx.declarator().directDeclarator().directDeclarator().getText() # 函数名
        self.function_name = function_name
        function_name1 = ctx.declarator().directDeclarator().getText() # 函数名
        function_body = ctx.compoundStatement().getText() # 函数体
        self.functions.append(function_name)
        print(f'函数名---{function_name}')

    # def enterParameterDeclaration(self, ctx):
    #     parameter_name = ctx.declarator().directDeclarator().getText()
    #     # print(f'参数---{parameter_name}')
    #     print(1111111111111)
        # self.parameters.setdefault(self.function_name,[]).append(parameter_name)
    
    # def enterComment(self, ctx):
    #     comment_text = ctx.getText()
    #     self.comments.append(comment_text)

    # def enterMacroDefinition(self, ctx):
    #     macro_name = ctx.macro_name().getText()
    #     macro_value = ctx.macro_value().getText()
    #     # 在这里处理宏定义
    #     self.macros.append(macro_name)
    #     print(f'宏定义名---{macro_name}')
# import codecs

# def toGb2312(file_path):
#     """
#     将.c/.h文件转成GB2312的编码格式
#     Args:
#         file_path (string): 文件路径
#     """
#     # 打开待转换文件并指定当前编码格式为UTF-8
#     with codecs.open(file_path, 'r') as file:
#         gb2312_content = file.read()
#     # # 将文件内容按照GB2312编码格式进行编码
#     # gb2312_content = content.encode('gb2312')
#     # 写入到新的文件中
#     output_file_path = file_path
#     with codecs.open(output_file_path, 'w', encoding='utf-8') as output_file:
#         output_file.write(gb2312_content)
#     with codecs.open(output_file_path, 'w', encoding='gb2312') as output_file:
#         output_file.write(gb2312_content)

def parse_c_file(file_path):
    with open(file_path, 'rb') as file:
        raw_data = file.read()
        result = chardet.detect(raw_data)
        encoding = result['encoding']
        confidence = result['confidence']
        print(f'99---{encoding},---{confidence}')
    # toGb2312(file_path)
    input_stream = FileStream(file_path)
    lexer = CLexer(input_stream)
    stream = CommonTokenStream(lexer)
    parser = CParser(stream)
    tree = parser.compilationUnit()

    # for child in tree.children:
    #     if isinstance(child, CParser.FunctionDefinitionContext):
    #         function_name = child.declarator().directDeclarator().getText()
    #         print(f"Found function: {function_name}")
    #     elif isinstance(child, CParser.MacroDefinitionContext):
    #         macro_name = child.getText()
    #         print(f"Found macro: {macro_name}")

    # hidden_tokens = stream.getHiddenTokensToLeft(5)
    # for token in hidden_tokens:
    #     print("Hidden Token:", token.text)

    listener = MyCListener()
    walker = ParseTreeWalker()
    walker.walk(listener, tree)

    functions = listener.functions
    comments = listener.comments
    macros = listener.macros
    parameters = listener.parameters

    return functions, comments, macros,parameters

# 示例用法
file_name12 = 'hk32t010_adc.h'
# file_name12 = 'hk32t010_comp.c'
functions, comments, macros,parameters = parse_c_file(file_name12)
print("函数:", functions)
print("函数参数:", parameters)
print("注释:", comments)
print("宏定义:", macros)

# # 定义一个访问器类，继承自 ParserListener,Visitor
# from CVisitor import CVisitor
# class MyVisitor(CVisitor):
#     def visitFunctionDefinition(self, ctx):
#         # 处理函数定义
#         function_name = ctx.functionName().getText()
#         function_body = ctx.compoundStatement().getText()
#         function_parameters = []
#         for parameter in ctx.parameterList().parameterDeclaration():
#             parameter_type = parameter.declarationSpecifiers().getText()
#             parameter_name = parameter.declarator().getText()
#             function_parameters.append((parameter_type, parameter_name))
#         # ...
#     def visitComment(self, ctx):
#         # 处理注释
#         comment_text = ctx.getText()
#         # ...
#     def visitMacroDefinition(self, ctx):
#         # 处理宏定义
#         macro_name = ctx.macroName().getText()
#         macro_value = ctx.macroValue().getText()
#         # ...
# visitor = MyVisitor()
# visitor.visit(root)


# # 定义一个访问器类，继承自 YourGrammarParserListener
# from CListener import CListener
# class MyListener(CListener):
#     def enterFunctionDefinition(self, ctx):
#         # 进入函数定义时的处理逻辑
        
#         function_name = ctx.functionName().getText()
#         print("Function:", function_name)
#         # 处理函数定义
#         function_name = ctx.functionName().getText()
#         function_body = ctx.compoundStatement().getText()
#         function_parameters = []
#         for parameter in ctx.parameterList().parameterDeclaration():
#             parameter_type = parameter.declarationSpecifiers().getText()
#             parameter_name = parameter.declarator().getText()
#             function_parameters.append((parameter_type, parameter_name))

#     # def enterComment(self, ctx):
#     #     # 进入注释时的处理逻辑
#     #     comment_text = ctx.getText()
#     #     print("Comment:", comment_text)

#     def enterMacroDefinition(self, ctx):
#         # 进入宏定义时的处理逻辑
#         macro_name = ctx.macroName().getText()
#         macro_value = ctx.macroValue().getText()
#         print("Macro:", macro_name)
# # 创建一个监听器对象
# listener = MyListener()
# # 遍历解析树，触发监听器中的相应方法
# # listener.enterMacroDefinition()
# walker = ParseTreeWalker()
# walker.walk(listener, parse_tree)

# # 定义一个访问器类，继承自 CParserVisitor
# class MyVisitor(CParserVisitor):
#     def visitFunctionDefinition(self, ctx):
#         # 访问函数定义时的处理逻辑
#         function_name = ctx.declarator().directDeclarator().directDeclarator().getText()
#         print("Function:", function_name)

#     def visitMacroDefinition(self, ctx):
#         # 访问宏定义时的处理逻辑
#         macro_name = ctx.macroDefinition().getText()
#         print("Macro:", macro_name)

#     def visitComment(self, ctx):
#         # 访问注释时的处理逻辑
#         comment_text = ctx.getText()
#         print("Comment:", comment_text)
# # 创建一个访问器对象
# visitor = MyVisitor()
# # 遍历解析树，触发访问器中的相应方法
# visitor.visit(parse_tree)


# from YourGrammarVisitor import YourGrammarVisitor
# class MyVisitor(YourGrammarVisitor):
#     def visitFunctionDefinition(self, ctx):
#         # 处理函数定义
#         function_name = ctx.functionName().getText()
#         function_body = ctx.compoundStatement().getText()
#         function_parameters = []
#         for parameter in ctx.parameterList().parameterDeclaration():
#             parameter_type = parameter.declarationSpecifiers().getText()
#             parameter_name = parameter.declarator().getText()
#             function_parameters.append((parameter_type, parameter_name))
#         # ...
#     def visitComment(self, ctx):
#         # 处理注释
#         comment_text = ctx.getText()
#         # ...
#     def visitMacroDefinition(self, ctx):
#         # 处理宏定义
#         macro_name = ctx.macroName().getText()
#         macro_value = ctx.macroValue().getText()
#         # ...
# visitor = MyVisitor()
# visitor.visit(root)